﻿using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Xml.Linq;
using System.Text.RegularExpressions;
using System.Windows.Media.Media3D;

namespace EnvSafe.SWViewer
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            diaopen = new OpenFileDialog();
            diaopen.Filter = "*.xaml|*.xaml|*.xml|*.xml|*.*|*.*";

            DataContext = this;
        }

        public Properties.Settings Settings { get { return Properties.Settings.Default; } }

        OpenFileDialog diaopen;
        private void MenuOpen_Click(object sender, RoutedEventArgs e)
        {
            if (diaopen.ShowDialog() == true)
            {
                LayoutRoot.Children.Clear();

                var ns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation";
                var ns_x = "http://schemas.microsoft.com/winfx/2006/xaml";
                var ns_helix = "clr-namespace:HelixToolkit.Wpf;assembly=HelixToolkit.Wpf";
                var ns_w3c = "http://www.w3.org/2000/xmlns/";

                var stream = diaopen.OpenFile();
                var xdoc = XDocument.Load(diaopen.OpenFile());
                var port = xdoc.Root;
                if (port.Name.LocalName == "Viewport3D")
                {
                    port.Name = XName.Get("HelixViewport3D", ns_helix);
                    port.SetAttributeValue(XName.Get("helix", ns_w3c), ns_helix);
                    port.SetAttributeValue("ModelUpDirection", "0,1,0");
                    var camgrp = port.Element(XName.Get("Viewport3D.Camera", ns));
                    if (camgrp != null)
                    {
                        camgrp.Name = XName.Get("HelixViewport3D.DefaultCamera", ns_helix);
                        var camcores = camgrp.Elements(XName.Get("OrthographicCamera", ns));
                        foreach (var cam in camcores)
                        {
                            cam.Name = XName.Get("PerspectiveCamera", ns);
                            cam.SetAttributeValue("Width", null);
                            cam.SetAttributeValue("NearPlaneDistance", null);
                            cam.SetAttributeValue("FarPlaneDistance", null);
                        }
                    }
                    var children = port.Element(XName.Get("Viewport3D.Children", ns));
                    if (children != null)
                    {
                        children.Name = XName.Get("HelixViewport3D.Children", ns_helix);
                    }
                }
                stream.Close();

                try
                {
                    var obj = (UIElement)(XamlReader.Parse(xdoc.ToString()));
                    LayoutRoot.Children.Add(obj);
                    if (Settings.Border)
                    {
                        List<MeshGeometry3D> n3os = new List<MeshGeometry3D>();
                        GetEdges(obj, n3os);
                    }
                }
                catch(Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }

        void GetEdges(DependencyObject obj, List<MeshGeometry3D> container)
        {
            var collection = LogicalTreeHelper.GetChildren(obj);
            //todo: GetChildren returns empty collection
            foreach (var item in collection)
            {
                if (item is MeshGeometry3D)
                {
                    var n3o = MeshGeometry3DExtension.ToWireframe((MeshGeometry3D)item, 0.1);
                    container.Add(n3o);
                    var p = Heroius.Extension.TreeExtension.GetLogicParent((DependencyObject)item, typeof(Model3DGroup));
                    if (p!= null)
                    {
                        (p as Model3DGroup).Children.Add(new GeometryModel3D() { Geometry = n3o });
                    }
                }
                else if (item is DependencyObject)
                {
                    GetEdges((DependencyObject)item, container);
                }
            }
        }

        private void MenuSetting_Click(object sender, RoutedEventArgs e)
        {
            new SettingWindow().ShowDialog();
        }
    }
}
